package com.ontheroad.core.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ontheroad.central.model.CentralBindEntity;
import com.ontheroad.central.model.CentralEntity;
import com.ontheroad.central.model.CentralPositionEntity;
import com.ontheroad.central.service.CentralBindTopicService;
import com.ontheroad.central.service.CentralPositionService;
import com.ontheroad.central.service.CentralTopicService;
import com.ontheroad.device.model.CentralDeviceDto;
import com.ontheroad.device.model.DeviceDto;
import com.ontheroad.device.model.DeviceEntity;
import com.ontheroad.device.model.DeviceStatusEntity;
import com.ontheroad.device.service.DeviceStatusTopicService;
import com.ontheroad.device.service.DeviceTopicService;
import com.ontheroad.group.model.DeviceGroupEntity;
import com.ontheroad.group.model.LinkageGroupEntity;
import com.ontheroad.group.model.TimingGroupEntity;
import com.ontheroad.group.service.DeviceGroupService;
import com.ontheroad.group.service.LinkageGroupService;
import com.ontheroad.group.service.TimingGroupService;
import com.ontheroad.logs.model.AlarmEntity;
import com.ontheroad.logs.model.CentralStatusEntity;
import com.ontheroad.logs.model.LogEntity;
import com.ontheroad.logs.model.ManagerEntity;
import com.ontheroad.logs.model.UserControlEntity;
import com.ontheroad.logs.service.AlarmService;
import com.ontheroad.logs.service.CentralStatusService;
import com.ontheroad.logs.service.LogService;
import com.ontheroad.logs.service.ManagerService;
import com.ontheroad.logs.service.UserControlService;
import com.ontheroad.scene.model.SceneEntity;
import com.ontheroad.scene.service.SceneService;
import com.ontheroad.user.model.HeartbeatEntity;
import com.ontheroad.user.model.UserDto;
import com.ontheroad.user.service.HeartbeatService;
import com.ontheroad.user.service.UserTopicService;
import com.ontheroad.utils.JsonUtils;

/**
 * 发布消息的回调类
 * 
 * 必须实现MqttCallback的接口并实现对应的相关接口方法CallBack 类将实现 MqttCallBack。
 * 每个客户机标识都需要一个回调实例。在此示例中，构造函数传递客户机标识以另存为实例数据。 在回调中，将它用来标识已经启动了该回调的哪个实例。
 * 必须在回调类中实现三个方法：
 * 
 * public void messageArrived(MqttTopic topic, MqttMessage message)接收已经预订的发布。
 * 
 * public void connectionLost(Throwable cause)在断开连接时调用。
 * 
 * public void deliveryComplete(MqttDeliveryToken token)) 接收到已经发布的 QoS 1 或 QoS 2
 * 消息的传递令牌时调用。 由 MqttClient.connect 激活此回调。
 * 
 */
public class PushCallback implements MqttCallback {

	private Logger log = LoggerFactory.getLogger(PushCallback.class);

	public void connectionLost(Throwable cause) {
		// 连接丢失后，一般在这里面进行重连
		System.out.println("连接断开，可以做重连");
	}

	public void deliveryComplete(IMqttDeliveryToken token) {
		System.out.println("deliveryComplete---------" + token.isComplete());
	}

	public void messageArrived(String topic, MqttMessage message)
			throws Exception {
		try {
			// subscribe后得到的消息会执行到这里面
			System.out.println("接收消息主题 : " + topic);
			log.info("--------------------------------------------------");
			System.out.println("接收消息Qos : " + message.getQos());
			String a = new String(message.getPayload());
			System.out.println("接收消息内容 : " + a);
			if ("v1/register/request".equals(topic) && !"close".equals(a)) {
				UserTopicService userTopicService = (UserTopicService) ApplicationContextHelper
						.getBean("userTopicService");
				UserDto user = (UserDto) JsonUtils.jsonToObject(a,
						UserDto.class);
				HashMap<String, Object> map = userTopicService.regist(user);
				String phone = user.getUser();
				ServerMQTT server = new ServerMQTT();
				server.message = new MqttMessage();
				server.message.setQos(2);
				server.message.setRetained(true);
				server.message.setPayload(JSONObject.toJSONString(map)
						.getBytes());
				MqttTopic topic12 = server.client.getTopic("v1/register/"
						+ phone + "/response");
				server.publish(topic12, server.message);
			}
			if (topic.contains("v1/login") && !"close".equals(a)) {
				if (!topic.contains("all")) {
					UserTopicService userTopicService = (UserTopicService) ApplicationContextHelper
							.getBean("userTopicService");
					UserDto user = (UserDto) JsonUtils.jsonToObject(a,
							UserDto.class);
					String phone = topic.split("/")[2];
					if (!phone.equals("+")) {
						HashMap<String, Object> map = userTopicService
								.login(user);
						ServerMQTT server = new ServerMQTT();
						server.message = new MqttMessage();
						server.message.setQos(2);
						server.message.setRetained(true);
						server.message.setPayload(JSONObject.toJSONString(map)
								.getBytes());
						MqttTopic topic12 = server.client.getTopic("v1/login/"
								+ phone + "/response");
						server.publish(topic12, server.message);
					}
				}
			}
			if ("v1/resetPasswrod/request".equals(topic) && !"close".equals(a)) {
				UserTopicService userTopicService = (UserTopicService) ApplicationContextHelper
						.getBean("userTopicService");
				UserDto user = (UserDto) JsonUtils.jsonToObject(a,
						UserDto.class);
				String phone = user.getUser();
				HashMap<String, Object> map = userTopicService
						.resetPasswrod(user);
				ServerMQTT server = new ServerMQTT();
				server.message = new MqttMessage();
				server.message.setQos(2);
				server.message.setRetained(true);
				server.message.setPayload(JSONObject.toJSONString(map)
						.getBytes());
				MqttTopic topic12 = server.client.getTopic("v1/resetPasswrod/"
						+ phone + "/response");
				server.publish(topic12, server.message);
			}
			if (topic.contains("/data/response") && !"close".equals(a)) {
				JSONObject jo = JSONObject.parseObject(a);
				int cmd = jo.getIntValue("cmd");
				String phone = topic.split("/")[2];
				if (cmd == 1001 && !phone.equals("+")) {
					CentralEntity central = (CentralEntity) JsonUtils
							.jsonToObject(a, CentralEntity.class);
					CentralTopicService centralTopicService = (CentralTopicService) ApplicationContextHelper
							.getBean("centralTopicService");
					centralTopicService.insertCentral(central);
				}
				if (cmd == 2001 && !phone.equals("+")) {
					String devices = jo.getString("devices");
					Boolean isSub = jo.getBoolean("isSub");
					int channel = jo.getIntValue("channel");
					String mac = jo.getString("mac");
					List<DeviceEntity> deviceList = (List) JsonUtils.getBeans(
							devices, DeviceEntity.class);
					DeviceDto deviceDto = new DeviceDto();
					deviceDto.setChannel(channel);
					deviceDto.setCmd(cmd);
					deviceDto.setIsSub(isSub);
					deviceDto.setMac(mac);
					deviceDto.setDevices(deviceList);
					DeviceTopicService deviceTopicService = (DeviceTopicService) ApplicationContextHelper
							.getBean("deviceTopicService");
					deviceTopicService.insertDeviceList(deviceDto);
				}
				if (cmd == 2002 && !phone.equals("+")) {
					CentralDeviceDto centralDeviceDto = (CentralDeviceDto) JsonUtils
							.jsonToObject(a, CentralDeviceDto.class);
					DeviceTopicService deviceTopicService = (DeviceTopicService) ApplicationContextHelper
							.getBean("deviceTopicService");
					deviceTopicService.modifyDevice(centralDeviceDto);
				}
				if (cmd == 2003 && !phone.equals("+")) {
					String devices = jo.getString("devices");
					Boolean isSub = jo.getBoolean("isSub");
					int channel = jo.getIntValue("channel");
					String mac = jo.getString("mac");
					List<DeviceStatusEntity> destaList = (List) JsonUtils
							.getBeans(devices, DeviceStatusEntity.class);
					DeviceStatusTopicService deviceStatusTopicService = (DeviceStatusTopicService) ApplicationContextHelper
							.getBean("deviceStatusTopicService");
					deviceStatusTopicService.insertDeviceStatusList(isSub,
							channel, mac, destaList);
				}

			}
			if (topic.contains("/data/request") && !"close".equals(a)) {
				JSONObject jo = JSONObject.parseObject(a);
				int cmd = jo.getIntValue("cmd");
				String phone = topic.split("/")[2];
				SceneEntity sceneEntity = new SceneEntity();
				if (cmd != 3001 && cmd != 3006 && cmd != 3007 && cmd != 3008
						&& cmd != 3002) {
					String scene = jo.getString("scene");
					sceneEntity = (SceneEntity) JsonUtils.jsonToObject(scene,
							SceneEntity.class);
				}
				Boolean isSub = jo.getBoolean("isSub");
				int channel = jo.getIntValue("channel");
				String mac = jo.getString("mac");

				SceneService sceneService = (SceneService) ApplicationContextHelper
						.getBean("sceneService");
				HashMap<String, Object> map = new HashMap<String, Object>();
				if (cmd == 3002 && !phone.equals("+")) {
					int sceneId = jo.getIntValue("scene");
					map = sceneService.findScenesInfo(sceneId);
					map.put("scene", sceneId);
					map.put("isSub", isSub);
					map.put("channel", channel);
					map.put("mac", mac);
				}
				if (cmd == 3003 && !phone.equals("+")) {
					map = sceneService.insertScene(isSub, channel, mac,
							sceneEntity);
				}
				if (cmd == 3004 && !phone.equals("+")) {
					map = sceneService.modifyScene(isSub, channel, mac,
							sceneEntity);
				}
				if (cmd == 3005 && !phone.equals("+")) {
					map = sceneService.deleteScene(isSub, channel, mac,
							sceneEntity);
				}
				if (cmd == 3001 && !phone.equals("+")) {
					map = sceneService.findScenes(isSub, channel, mac);
				}
				if (cmd == 3006 && !phone.equals("+")) {
					int sceneid = jo.getIntValue("sceneid");
					String timing = jo.getString("timing");
					int scene = jo.getIntValue("scene");
					TimingGroupEntity timingGroupEntity = (TimingGroupEntity) JsonUtils
							.jsonToObject(timing, TimingGroupEntity.class);
					TimingGroupService timingGroupService = (TimingGroupService) ApplicationContextHelper
							.getBean("timingGroupService");
					map = timingGroupService.insertTimingGroup(sceneid,
							timingGroupEntity);
					map.put("scene", scene);
					map.put("isSub", isSub);
					map.put("channel", channel);
					map.put("mac", mac);
					map.put("sceneid", sceneid);
				}
				if (cmd == 3007 && !phone.equals("+")) {
					int sceneid = jo.getIntValue("sceneid");
					String device = jo.getString("device");
					int scene = jo.getIntValue("scene");
					DeviceGroupEntity deviceGroupEntity = (DeviceGroupEntity) JsonUtils
							.jsonToObject(device, DeviceGroupEntity.class);
					DeviceGroupService deviceGroupService = (DeviceGroupService) ApplicationContextHelper
							.getBean("deviceGroupService");
					map = deviceGroupService.insertDeviceGroup(sceneid,
							deviceGroupEntity);
					map.put("scene", scene);
					map.put("isSub", isSub);
					map.put("channel", channel);
					map.put("mac", mac);
					map.put("sceneid", sceneid);
				}
				if (cmd == 3008 && !phone.equals("+")) {
					int sceneid = jo.getIntValue("sceneid");
					String linkages = jo.getString("linkages");
					int scene = jo.getIntValue("scene");
					LinkageGroupEntity linkageGroupEntity = (LinkageGroupEntity) JsonUtils
							.jsonToObject(linkages, LinkageGroupEntity.class);
					LinkageGroupService linkageGroupService = (LinkageGroupService) ApplicationContextHelper
							.getBean("linkageGroupService");
					map = linkageGroupService.insertLinkageGroup(sceneid,
							linkageGroupEntity);
					map.put("scene", scene);
					map.put("isSub", isSub);
					map.put("channel", channel);
					map.put("mac", mac);
					map.put("sceneid", sceneid);
				}
				map.put("cmd", cmd);
				ServerMQTT server = new ServerMQTT();
				server.message = new MqttMessage();
				server.message.setQos(2);
				server.message.setRetained(true);
				server.message.setPayload(JSONObject.toJSONString(map)
						.getBytes());
				MqttTopic topic12 = server.client
						.getTopic("v1/cloud/all/data/response");
				server.publish(topic12, server.message);

			}
			if ("v1/bind/request".equals(topic) && !"close".equals(a)) {
				CentralBindTopicService centralBindTopicService = (CentralBindTopicService) ApplicationContextHelper
						.getBean("centralBindTopicService");
				CentralBindEntity centralBindEntity = (CentralBindEntity) JsonUtils
						.jsonToObject(a, CentralBindEntity.class);
				String phone = centralBindEntity.getUser();
				HashMap<String, Object> map = centralBindTopicService
						.bind(centralBindEntity);
				ServerMQTT server = new ServerMQTT();
				server.message = new MqttMessage();
				server.message.setQos(2);
				server.message.setRetained(true);
				server.message.setPayload(JSONObject.toJSONString(map)
						.getBytes());
				MqttTopic topic12 = server.client.getTopic("v1/bind/" + phone
						+ "/response");
				server.publish(topic12, server.message);
			}
			if ("v1/unbind/request".equals(topic) && !"close".equals(a)) {
				CentralBindTopicService centralBindTopicService = (CentralBindTopicService) ApplicationContextHelper
						.getBean("centralBindTopicService");
				CentralBindEntity centralBindEntity = (CentralBindEntity) JsonUtils
						.jsonToObject(a, CentralBindEntity.class);
				String phone = centralBindEntity.getUser();
				HashMap<String, Object> map = centralBindTopicService
						.unbind(centralBindEntity);
				ServerMQTT server = new ServerMQTT();
				server.message = new MqttMessage();
				server.message.setQos(2);
				server.message.setRetained(true);
				server.message.setPayload(JSONObject.toJSONString(map)
						.getBytes());
				MqttTopic topic12 = server.client.getTopic("v1/unbind/" + phone
						+ "/response");
				server.publish(topic12, server.message);
			}
			if (topic.contains("/heartbeat/request") && !"close".equals(a)) {
				String phone = topic.split("/")[2];
				String central_mac = topic.split("/")[1];
				if (!phone.equals("+")) {
					HeartbeatService heartbeatService = (HeartbeatService) ApplicationContextHelper
							.getBean("heartbeatService");
					HeartbeatEntity heartbeatEntity = new HeartbeatEntity();
					heartbeatEntity.setMac(central_mac);
					heartbeatEntity.setUser(phone);
					HashMap<String, Object> map = heartbeatService.insertHeart(heartbeatEntity);
					ServerMQTT server = new ServerMQTT();
					server.message = new MqttMessage();
					server.message.setQos(2);
					server.message.setRetained(true);
					server.message.setPayload(JSONObject.toJSONString(map)
							.getBytes());
					MqttTopic topic12 = server.client.getTopic("v1/"+central_mac+"/"
							+ phone + "/heartbeat/response");
					server.publish(topic12, server.message);
				}
			}
			if (topic.contains("/control/device") && !"close".equals(a)) {
				String phone = topic.split("/")[2];
				if (!phone.equals("+")) {
					UserControlService userControlService = (UserControlService) ApplicationContextHelper
							.getBean("userControlService");
					UserControlEntity userControlEntity = (UserControlEntity) JsonUtils
							.jsonToObject(a, UserControlEntity.class);
					userControlService.insertUserControl(userControlEntity);
				}
			}
			if (topic.contains("/state/type") && !"close".equals(a)) {
				String phone = topic.split("/")[2];
				if (!phone.equals("+")) {
					CentralStatusService centralStatusService = (CentralStatusService) ApplicationContextHelper
							.getBean("centralStatusService");
					CentralStatusEntity centralStatusEntity = (CentralStatusEntity) JsonUtils
							.jsonToObject(a, CentralStatusEntity.class);
					centralStatusService
							.insertCentralStatus(centralStatusEntity);
				}
			}
			if (topic.contains("/dbversion/request") && !"close".equals(a)) {
				String phone = topic.split("/")[2];
				String central_mac = topic.split("/")[1];
				if (!phone.equals("+")) {
					CentralTopicService centralTopicService = (CentralTopicService) ApplicationContextHelper
							.getBean("centralTopicService");
					HashMap<String, Object> map = centralTopicService
							.findCentralVersion(central_mac);
					ServerMQTT server = new ServerMQTT();
					server.message = new MqttMessage();
					server.message.setQos(2);
					server.message.setRetained(true);
					server.message.setPayload(JSONObject.toJSONString(map)
							.getBytes());
					MqttTopic topic12 = server.client
							.getTopic("v1/" + central_mac + "/" + phone
									+ "/dbversion/response");
					server.publish(topic12, server.message);
				}

			}
			if (topic.contains("/manage/request") && !"close".equals(a)) {
				String phone = topic.split("/")[2];
				String central_mac = topic.split("/")[1];
				JSONObject jo = JSONObject.parseObject(a);
				int id = jo.getIntValue("id");
				if (!phone.equals("+")) {
					ManagerService managerService = (ManagerService) ApplicationContextHelper
							.getBean("managerService");
					ManagerEntity managerEntity = new ManagerEntity();
					managerEntity.setSqlId(id);
					managerEntity.setMac(central_mac);
					managerEntity.setUser(phone);
					managerEntity.setSql(a);
					managerService.insertManager(managerEntity);
				}
			}
			if ("v1/cloud".equals(topic) && !"close".equals(a)) {
				JSONObject jo = JSONObject.parseObject(a);
				String centrals = jo.getString("centrals");
				List<String> macList = (List<String>) JSONArray.parseArray(
						centrals, String.class);
				jo.remove("centrals");
				CentralPositionService centralPositionService = (CentralPositionService) ApplicationContextHelper
						.getBean("centralPositionService");
				CentralPositionEntity centralPositionEntity = (CentralPositionEntity) JsonUtils
						.jsonToObject(JSONObject.toJSONString(jo),
								CentralPositionEntity.class);
				for (String mac : macList) {
					centralPositionEntity.setMac(mac);
					centralPositionService.insertCentPos(centralPositionEntity);
				}
			}
			if ("v1/log".equals(topic) && !"close".equals(a)) {
				LogService logService = (LogService) ApplicationContextHelper
						.getBean("logService");
				LogEntity logEntity = (LogEntity) JsonUtils.jsonToObject(a,
						LogEntity.class);
				logService.insertLog(logEntity);
			}
			if (topic.contains("/alarm") && !"close".equals(a)) {
				String phone = topic.split("/")[2];
				if (!phone.equals("+")) {
					AlarmService alarmService = (AlarmService) ApplicationContextHelper
							.getBean("alarmService");
					AlarmEntity alarmEntity = (AlarmEntity) JsonUtils
							.jsonToObject(a, AlarmEntity.class);
					if (alarmEntity.getPhone() == null
							| "".equals(alarmEntity.getPhone())) {
						alarmEntity.setPhone(phone);
					}
					alarmService.insertLog(alarmEntity);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}